/**
 * 模型及地形的裁剪
 */
class DClipVolume {
  constructor ( v, e ) {
    if ( e ) {
      this._canvas = e || Module.qtCanvasElements[0]
    }
    this._inputEvents = {}
    this._viewer = v
    //剪切实体
    this.ClipFlag = {
      0: SSmap.ClipVolumeFlag.ClipAll, //裁切所有
      1: SSmap.ClipVolumeFlag.ClipGlobe, //裁切球体
      2: SSmap.ClipVolumeFlag.ClipScene //裁切场景
    }
    //累计距离
    this._cumdistance = 0 //米 延长距离
    //this._tblrdistance = 0;//米 东南西北
    this._minclipaltitude = 1 //米 最低裁切海拔
    this._nowclipdistance = 1 //米 当前裁切距离
    this._maxclipaltitude = 800 //米 最高裁切海拔
    //裁切立体 集合
    this.ClipCubeCollection = {}
    this._clippolygonCollection = {}
    //需要裁切的对象
    this._ClipEObject = null
    this._callBack = null
    //需要创建的实体 类
    // try {
    //   this._Entity = new GeometryEntity(v);
    // } catch (error) {
    //   console.log(error);
    // }
  }
  
  //创建裁剪
  createdClip ( opt ) {
    //裁切体限制
    var objectnum = Object.getOwnPropertyNames(
      this.ClipCubeCollection
    ).length
    if ( objectnum >= 8 ) {
      console.error(
        'RangeError :',
        'Maximum call ClipVolume value exceeded'
      )
      return
    }
    //相同id 不同重复创建
    if ( this.ClipCubeCollection[opt.entityid] ) {
      console.error(
        'RuntimeError :',
        'An ClipVolume with id ' +
        opt.entityid +
        ' already exists in this collection.'
      )
      return
    }
    opt = opt || {}
    let cv = new SSmap.ClipVolume()
    cv.shape = SSmap.ClipVolumeShape.Cube //剪切形状, 默认Cube立方体 Cylinder
    cv.clipFlag = this.ClipFlag[opt.flag || 0] //默认是全部剪切, 可选ClipGlobe只裁切球体, ClipScene只裁切场景, ClipAll
    let clipwidth = opt.clipwidth || 100 //宽度 默认100
    let cliplength = opt.cliplength || 100 //长度 默认100
    let clipheight = opt.clipheight || 1 //高度 默认1
    cv.size = SSmap.Vector3.create(
      clipwidth / 2,
      cliplength / 2,
      clipheight / 2
    ) // clipwidth x cliplength x clipheight 米的剪切体
    cv.showDebugVolume = opt.contour === undefined ? true : opt.contour //是否显示剪切的轮廓
    cv.objectName = opt.name || this._getentityid() //添加一个名称标识
    let nowentity = new SSmap.Entity()
    let rotations
    if ( opt.rotations ) {
      rotations = SSmap.Quaternion.fromEulerAngles(
        opt.rotations[0],
        opt.rotations[1],
        opt.rotations[2]
      )
    } else {
      rotations = SSmap.Quaternion.fromEulerAngles( 0, 0, 0 )
    }
    nowentity.transform.cartographic = opt.centerc //坐标点
    let nowchildEntity = new SSmap.Entity() //子物体
    nowchildEntity.parent = nowentity //设置父子结构
    nowchildEntity.transform.rotation = rotations //旋转角度(四元数)
    nowchildEntity.id = opt.Eclipid || this._getentityid()
    nowchildEntity.addComponent( cv ) //添加组件
    this._viewer.scene.addEntity( nowentity ) //添加到rootEntity的子节点中
    this.ClipCubeCollection[opt.Eclipid] = {
      clipvolume: cv,
      entity: nowentity,
      childEntity: nowchildEntity,
      type: opt.cliptype,
      nowclipheight: this._nowclipdistance,
      optobject: opt
    }
  }
  
  //显示辅助面
  showClipPolygon ( bol, id ) {
    var objectnum = Object.getOwnPropertyNames(
      this.ClipCubeCollection
    ).length
    
    if ( objectnum > 0 ) {
      if ( id ) {
        this._clippolygonCollection[id].enabled = bol
      } else {
        for ( var keys in this._clippolygonCollection ) {
          this._clippolygonCollection[keys].enabled = bol
        }
      }
    }
    // else {
    //   console.error('RuntimeError :', "undefined ClipVolume");
    // }
  }
  
  //移除裁剪
  removeClipAll () {
    var objectnum = Object.getOwnPropertyNames(
      this.ClipCubeCollection
    ).length
    if ( objectnum > 0 ) {
      for ( var key in this.ClipCubeCollection ) {
        this.ClipCubeCollection[key].clipvolume.delete()
        this.ClipCubeCollection[key].entity.delete()
        delete this.ClipCubeCollection[key]
      }
      
      for ( var keys in this._clippolygonCollection ) {
        this._clippolygonCollection[keys].delete()
        delete this.ClipCubeCollection[keys]
      }
    }
  }
  
  /**
   * 根据id移除裁切体和辅助面
   * @param {*} id
   */
  removeClipById ( id ) {
    var objectnum = Object.getOwnPropertyNames(
      this.ClipCubeCollection
    ).length
    if ( objectnum > 0 ) {
      this.ClipCubeCollection[id].clipvolume.delete()
      this.ClipCubeCollection[id].entity.delete()
      delete this.ClipCubeCollection[id]
      
      this._clippolygonCollection[id].delete()
      delete this.ClipCubeCollection[id]
    }
  }
  
  /**
   * 底部裁剪
   */
  bottomClip ( opt ) {
    if ( this.ClipCubeCollection[opt.clipid] ) {
      console.error(
        'RuntimeError :',
        'An ClipVolume with id ' +
        opt.clipid +
        ' already exists in this collection.'
      )
      return
    }
    opt = opt || {}
    let nowcontour = opt.contour === undefined ? false : opt.contour
    this._nowclipdistance = opt.cdistance || this._nowclipdistance
    this._ClipEObject = opt.clipobject
    if ( opt.clipobject ) {
      let maxminopt = this.getTilesrectangle( this._ClipEObject ) //最大最小
      let centerpoint = this._gettpointCenter(
        maxminopt.maxmin,
        opt.cdistance / 2
      ) //中心点
      //计算长宽 及角度
      let Coptwihean = this._getwidthheightangle(
        maxminopt.recposition,
        centerpoint
      )
      //生成裁切面
      let Popt = {
        polygonid: opt.clipid,
        isshow: nowcontour,
        alpha: 0.5,
        center: centerpoint
      }
      this.addCPolygon3D( maxminopt.maxmin, Popt, 0.1 )
      let clipopt = {
        flag: 2, //裁切对象
        clipwidth: opt.clipwidth || Coptwihean.width, //宽度
        cliplength: opt.cliplength || Coptwihean.height, //长度
        clipheight: this._nowclipdistance, //高度
        contour: nowcontour,
        centerc: centerpoint.toCartographic(),
        rotations: [ 0, 0, 0 ], //暂时不给
        Eclipid: opt.clipid, //
        cliptype: 'bottomClip'
      }
      this.createdClip( clipopt )
    } else {
      console.error( 'RuntimeError :', 'Clip Object is undefined' )
    }
  }
  
  /**
   * 顶部裁剪
   * @param {*} opt
   * @returns
   */
  topClip ( opt ) {
    if ( this.ClipCubeCollection[opt.clipid] ) {
      console.error(
        'RuntimeError :',
        'An ClipVolume with id ' +
        opt.clipid +
        ' already exists in this collection.'
      )
      return
    }
    opt = opt || {}
    let nowcontour = opt.contour === undefined ? false : opt.contour
    this._nowclipdistance = opt.cdistance || 1
    this._ClipEObject = opt.clipobject
    if ( opt.clipobject ) {
      var centerheight =
        ( this._maxclipaltitude - this._nowclipdistance ) / 2
      
      let maxminopt = this.getTilesrectangle( this._ClipEObject ) //最大最小
      let centerpoint = this._gettpointCenter(
        maxminopt.maxmin,
        centerheight
      ) //中心点
      //计算长宽 及角度
      let Coptwihean = this._getwidthheightangle(
        maxminopt.recposition,
        centerpoint
      )
      let Popt = {
        polygonid: opt.clipid,
        isshow: nowcontour,
        alpha: 0.5,
        center: centerpoint
      }
      this.addCPolygon3D( maxminopt.maxmin, Popt, -0.1 )
      let clipopt = {
        flag: 2, //裁切对象
        clipwidth: opt.clipwidth ? opt.clipwidth : Coptwihean.width, //宽度
        cliplength: opt.cliplength ? opt.cliplength : Coptwihean.height, //长度
        clipheight: ( centerheight - this._nowclipdistance ) * 2, //高度
        contour: nowcontour,
        centerc: centerpoint.toCartographic(),
        rotations: [ 0, 0, 0 ], //暂时不给
        Eclipid: opt.clipid, //
        cliptype: 'topClip'
      }
      this.createdClip( clipopt )
    } else {
      console.error( 'RuntimeError :', 'Clip Object is undefined' )
    }
  }
  
  /**
   * 正东部裁剪
   * @param {*} opt
   * @returns
   */
  eastClip ( opt ) {
    if ( this.ClipCubeCollection[opt.clipid] ) {
      console.error(
        'RuntimeError :',
        'An ClipVolume with id ' +
        opt.clipid +
        ' already exists in this collection.'
      )
      return
    }
    opt = opt || {}
    let nowcontour = opt.contour === undefined ? false : opt.contour
    this._nowclipdistance = opt.cdistance || 1 //当前裁剪距离
    this._ClipEObject = opt.clipobject //裁剪对象
    if ( opt.clipobject ) {
      let maxminopt = this.getTilesrectangle( this._ClipEObject ) //最大最小
      //辅助 裁切面
      let Popt = {
        polygonid: opt.clipid,
        isshow: nowcontour,
        pulygonheight: opt.pheight || 300,
        type: 'east'
      }
      var poobject = this.addDirPolygon3D(
        maxminopt.recposition,
        Popt,
        0.1
      )
      var nowheight = opt.clipheight || 300
      var centersquare = this._getcentersquare( poobject, nowheight )
      var newsquare = this._Vector3toCartesian3(
        centersquare.squareposition
      )
      let centerpoint = this._gettpointCenter( newsquare ) //中心点
      let clipopt = {
        flag: 2, //裁切对象
        clipwidth: opt.clipwidth || 0.1, //宽度
        cliplength: opt.cliplength || centersquare.distance, //长度
        clipheight: nowheight, //高度
        contour: nowcontour,
        centerc: centerpoint.toCartographic(),
        rotations: [ 0, 0, 0 ], //暂时不给
        Eclipid: opt.clipid, //
        cliptype: 'eastClip',
        polygonoopt: poobject
      }
      this.createdClip( clipopt )
    }
  }
  
  /**
   * 正南部裁剪
   * @param {*} opt
   * @returns
   */
  southClip ( opt ) {
    if ( this.ClipCubeCollection[opt.clipid] ) {
      console.error(
        'RuntimeError :',
        'An ClipVolume with id ' +
        opt.clipid +
        ' already exists in this collection.'
      )
      return
    }
    opt = opt || {}
    let nowcontour = opt.contour === undefined ? false : opt.contour //是否显示轮廓
    this._nowclipdistance = opt.cdistance || 1 //当前裁剪距离
    this._ClipEObject = opt.clipobject //裁剪对象
    if ( opt.clipobject ) {
      let maxminopt = this.getTilesrectangle( this._ClipEObject ) //最大最小
      //辅助 裁切面
      let Popt = {
        polygonid: opt.clipid,
        isshow: nowcontour,
        pulygonheight: opt.pheight || 300,
        type: 'south'
      }
      var poobject = this.addDirPolygon3D(
        maxminopt.recposition,
        Popt,
        0.1
      )
      
      var nowheight = opt.clipheight || 300
      var centersquare = this._getcentersquare( poobject, nowheight )
      var newsquare = this._Vector3toCartesian3(
        centersquare.squareposition
      )
      let centerpoint = this._gettpointCenter( newsquare ) //中心点
      let clipopt = {
        flag: 2, //裁切对象
        clipwidth: opt.clipwidth || centersquare.distance, //宽度
        cliplength: opt.cliplength || 0.1, //长度
        clipheight: nowheight, //高度
        contour: nowcontour,
        centerc: centerpoint.toCartographic(),
        rotations: [ 0, 0, 0 ], //暂时不给
        Eclipid: opt.clipid, //
        cliptype: 'southClip',
        polygonoopt: poobject
      }
      this.createdClip( clipopt )
    }
  }
  
  /**
   * 正西部裁剪
   * @param {*} opt
   * @returns
   */
  westClip ( opt ) {
    if ( this.ClipCubeCollection[opt.clipid] ) {
      console.error(
        'RuntimeError :',
        'An ClipVolume with id ' +
        opt.clipid +
        ' already exists in this collection.'
      )
      return
    }
    opt = opt || {}
    let nowcontour = opt.contour === undefined ? false : opt.contour
    this._nowclipdistance = opt.cdistance || 1 //当前裁剪距离
    this._ClipEObject = opt.clipobject //裁剪对象
    if ( opt.clipobject ) {
      let maxminopt = this.getTilesrectangle( this._ClipEObject ) //最大最小
      //辅助 裁切面
      let Popt = {
        polygonid: opt.clipid,
        isshow: nowcontour,
        pulygonheight: opt.pheight || 300,
        type: 'west'
      }
      var poobject = this.addDirPolygon3D(
        maxminopt.recposition,
        Popt,
        0.1
      )
      
      var nowheight = opt.clipheight || 300
      var centersquare = this._getcentersquare( poobject, nowheight )
      var newsquare = this._Vector3toCartesian3(
        centersquare.squareposition
      )
      let centerpoint = this._gettpointCenter( newsquare ) //中心点
      let clipopt = {
        flag: 2, //裁切对象
        clipwidth: opt.clipwidth || 0.1, //宽度
        cliplength: opt.cliplength || centersquare.distance, //长度
        clipheight: nowheight, //高度
        contour: nowcontour,
        centerc: centerpoint.toCartographic(),
        rotations: [ 0, 0, 0 ], //暂时不给
        Eclipid: opt.clipid, //
        cliptype: 'westClip',
        polygonoopt: poobject
      }
      this.createdClip( clipopt )
    }
  }
  
  /**
   * 正北部裁剪
   * @param {*} opt
   * @returns
   */
  northClip ( opt ) {
    if ( this.ClipCubeCollection[opt.clipid] ) {
      console.error(
        'RuntimeError :',
        'An ClipVolume with id ' +
        opt.clipid +
        ' already exists in this collection.'
      )
      return
    }
    opt = opt || {}
    let nowcontour = opt.contour === undefined ? false : opt.contour
    this._nowclipdistance = opt.cdistance || 1 //当前裁剪距离
    this._ClipEObject = opt.clipobject //裁剪对象
    if ( opt.clipobject ) {
      let maxminopt = this.getTilesrectangle( this._ClipEObject ) //最大最小
      //辅助 裁切面
      let Popt = {
        polygonid: opt.clipid,
        isshow: nowcontour,
        pulygonheight: opt.pheight || 300,
        type: 'north'
      }
      var poobject = this.addDirPolygon3D(
        maxminopt.recposition,
        Popt,
        0.1
      )
      
      var nowheight = opt.clipheight || 300
      var centersquare = this._getcentersquare( poobject, nowheight )
      var newsquare = this._Vector3toCartesian3(
        centersquare.squareposition
      )
      let centerpoint = this._gettpointCenter( newsquare ) //中心点
      let clipopt = {
        flag: 2, //裁切对象
        clipwidth: opt.clipwidth || centersquare.distance, //宽度
        cliplength: opt.cliplength || 0.1, //长度
        clipheight: nowheight, //高度
        contour: nowcontour,
        centerc: centerpoint.toCartographic(),
        rotations: [ 0, 0, 0 ], //暂时不给
        Eclipid: opt.clipid, //
        cliptype: 'northClip',
        polygonoopt: poobject
      }
      this.createdClip( clipopt )
    }
  }
  
  /**
   * 更新裁剪海拔
   */
  setDistanceById ( id, clipdistance ) {
    var nowoldheight = this._nowclipdistance - clipdistance
    this._nowclipdistance = clipdistance
    if ( this.ClipCubeCollection[id] ) {
      let nowcliptype = this.ClipCubeCollection[id].type
      let lonlats =
        this.ClipCubeCollection[
          id
          ].entity.transform.cartographic.toDegrees()
      let nowoptobject = this.ClipCubeCollection[id].optobject
      switch ( nowcliptype ) {
        case 'bottomClip':
          //底部裁剪
          if ( nowoptobject ) {
            this.ClipCubeCollection[id].optobject.clipheight =
              clipdistance
          }
          var width = nowoptobject.clipwidth || 100
          var length = nowoptobject.cliplength || 100
          this.ClipCubeCollection[id].clipvolume.size =
            SSmap.Vector3.create(
              width / 2,
              length / 2,
              clipdistance
            )
          this.ClipCubeCollection[id].entity.transform.cartographic =
            SSmap.Cartographic.fromDegrees(
              lonlats.longitude,
              lonlats.latitude,
              0
            ) //坐标
          if ( this._clippolygonCollection[id] ) {
            //面的海拔
            var lnum =
              this._clippolygonCollection[id].attribute.hnum ||
              0.1
            var nowEposition =
              this._clippolygonCollection[
                id
                ].transform.cartographic.toDegrees()
            this._clippolygonCollection[id].transform.cartographic =
              SSmap.Cartographic.fromDegrees(
                nowEposition.longitude,
                nowEposition.latitude,
                nowEposition.height - nowoldheight
              )
          }
          break
        case 'topClip':
          //顶部裁剪
          if ( nowoptobject ) {
            this.ClipCubeCollection[id].optobject.clipheight =
              clipdistance
          }
          var centerheight =
            ( this._maxclipaltitude - clipdistance ) / 2
          var topwidth = nowoptobject.clipwidth || 100
          var toplength = nowoptobject.cliplength || 100
          this.ClipCubeCollection[id].clipvolume.size =
            SSmap.Vector3.create(
              topwidth / 2,
              toplength / 2,
              centerheight - clipdistance
            )
          this.ClipCubeCollection[id].entity.transform.cartographic =
            SSmap.Cartographic.fromDegrees(
              lonlats.longitude,
              lonlats.latitude,
              centerheight
            ) //坐标
          if ( this._clippolygonCollection[id] ) {
            //面的海拔
            var lnum1 =
              this._clippolygonCollection[id].attribute.hnum ||
              -0.1
            
            var nowEposition1 =
              this._clippolygonCollection[
                id
                ].transform.cartographic.toDegrees()
            this._clippolygonCollection[id].transform.cartographic =
              SSmap.Cartographic.fromDegrees(
                nowEposition1.longitude,
                nowEposition1.latitude,
                nowEposition1.height - nowoldheight
              )
          }
          break
        case 'eastClip':
          var nowv = null
          if ( nowoptobject ) {
            nowv = nowoptobject.polygonoopt.vector
          }
          //尺寸
          var eastwidth = nowoptobject.clipwidth - nowoldheight / 2
          var noweastwidth = eastwidth < 0.1 ? 0.05 : eastwidth
          var eastlength = nowoptobject.cliplength / 2 || 100
          var eastheight = nowoptobject.clipheight / 2 || 200
          this.ClipCubeCollection[id].clipvolume.size =
            SSmap.Vector3.create(
              noweastwidth,
              eastlength,
              eastheight
            )
          this.ClipCubeCollection[id].optobject.clipwidth =
            noweastwidth
          //裁切体坐标
          var clipposition =
            this.ClipCubeCollection[
              id
              ].entity.transform.cartographic.toCartesian3()
          var newnowoldheight = nowoldheight / 2
          if ( noweastwidth === 0.05 ) {
            newnowoldheight = nowoldheight
          }
          var newclipcartographic = this._getnewvectorposition(
            clipposition,
            nowv,
            newnowoldheight
          )
          this.ClipCubeCollection[id].entity.transform.cartographic =
            newclipcartographic
          //面
          if ( this._clippolygonCollection[id] ) {
            var nowEposition2 =
              this._clippolygonCollection[
                id
                ].transform.cartographic.toCartesian3()
            this._clippolygonCollection[id].transform.cartographic =
              this._getnewvectorposition(
                nowEposition2,
                nowv,
                nowoldheight
              )
          }
          break
        case 'southClip':
          var nowv1 = null
          if ( nowoptobject ) {
            nowv1 = nowoptobject.polygonoopt.vector
          }
          //尺寸
          var southwidth = nowoptobject.clipwidth / 2 || 100
          var southlength =
            nowoptobject.cliplength - nowoldheight / 2
          var nowsouthlength = southlength < 0.1 ? 0.05 : southlength
          var southheight = nowoptobject.clipheight / 2 || 200
          this.ClipCubeCollection[id].clipvolume.size =
            SSmap.Vector3.create(
              southwidth,
              nowsouthlength,
              southheight
            )
          this.ClipCubeCollection[id].optobject.cliplength =
            nowsouthlength
          //裁切体坐标
          var clippositions =
            this.ClipCubeCollection[
              id
              ].entity.transform.cartographic.toCartesian3()
          var newnowsouthlength = nowoldheight / 2
          if ( nowsouthlength === 0.05 ) {
            newnowsouthlength = nowoldheight
          }
          var newclipcartographic1 = this._getnewvectorposition(
            clippositions,
            nowv1,
            newnowsouthlength
          )
          this.ClipCubeCollection[id].entity.transform.cartographic =
            newclipcartographic1
          //面
          if ( this._clippolygonCollection[id] ) {
            var nowEposition3 =
              this._clippolygonCollection[
                id
                ].transform.cartographic.toCartesian3()
            this._clippolygonCollection[id].transform.cartographic =
              this._getnewvectorposition(
                nowEposition3,
                nowv1,
                nowoldheight
              )
          }
          break
        case 'westClip':
          var nowv2 = null
          if ( nowoptobject ) {
            nowv2 = nowoptobject.polygonoopt.vector
          }
          //尺寸
          var westwidth = nowoptobject.clipwidth - nowoldheight / 2
          var nowwestwidth = westwidth < 0.1 ? 0.05 : westwidth
          var westlength = nowoptobject.cliplength / 2 || 100
          var westheight = nowoptobject.clipheight / 2 || 200
          this.ClipCubeCollection[id].clipvolume.size =
            SSmap.Vector3.create(
              nowwestwidth,
              westlength,
              westheight
            )
          this.ClipCubeCollection[id].optobject.clipwidth =
            nowwestwidth
          //裁切体坐标
          var clippositionw =
            this.ClipCubeCollection[
              id
              ].entity.transform.cartographic.toCartesian3()
          var newnowoldheight1 = nowoldheight / 2
          if ( nowwestwidth === 0.05 ) {
            newnowoldheight1 = nowoldheight
          }
          var newclipcartographic2 = this._getnewvectorposition(
            clippositionw,
            nowv2,
            newnowoldheight1
          )
          this.ClipCubeCollection[id].entity.transform.cartographic =
            newclipcartographic2
          
          //面
          if ( this._clippolygonCollection[id] ) {
            var nowEposition4 =
              this._clippolygonCollection[
                id
                ].transform.cartographic.toCartesian3()
            this._clippolygonCollection[id].transform.cartographic =
              this._getnewvectorposition(
                nowEposition4,
                nowv2,
                nowoldheight
              )
          }
          break
        case 'northClip':
          var nowv3 = null
          if ( nowoptobject ) {
            nowv3 = nowoptobject.polygonoopt.vector
          }
          //尺寸
          var northwidth = nowoptobject.clipwidth / 2 || 100
          var northlength =
            nowoptobject.cliplength - nowoldheight / 2
          var nownorthlength = northlength < 0.1 ? 0.05 : northlength
          var northheight = nowoptobject.clipheight / 2 || 200
          this.ClipCubeCollection[id].clipvolume.size =
            SSmap.Vector3.create(
              northwidth,
              nownorthlength,
              northheight
            )
          this.ClipCubeCollection[id].optobject.cliplength =
            nownorthlength
          //裁切体坐标
          var clippositionn =
            this.ClipCubeCollection[
              id
              ].entity.transform.cartographic.toCartesian3()
          var newnownorthlength = nowoldheight / 2
          if ( nownorthlength === 0.05 ) {
            newnownorthlength = nowoldheight
          }
          var newclipcartographic3 = this._getnewvectorposition(
            clippositionn,
            nowv3,
            newnownorthlength
          )
          this.ClipCubeCollection[id].entity.transform.cartographic =
            newclipcartographic3
          
          //面
          if ( this._clippolygonCollection[id] ) {
            var nowEposition5 =
              this._clippolygonCollection[
                id
                ].transform.cartographic.toCartesian3()
            this._clippolygonCollection[id].transform.cartographic =
              this._getnewvectorposition(
                nowEposition5,
                nowv3,
                nowoldheight
              )
          }
          break
      }
    }
    // else {
    //   console.error('RuntimeError :', "An ClipVolume with id " + id + " no exists in this collection.");
    // }
  }
  
  //生成裁切面 上下
  addCPolygon3D ( maxminposition, opt, num ) {
    var objectnum = Object.getOwnPropertyNames(
      this.ClipCubeCollection
    ).length
    if ( objectnum >= 8 ) {
      console.error(
        'RangeError :',
        'Maximum call Polygon3D value exceeded'
      )
      return
    }
    //相同id 不同重复创建
    if ( this.ClipCubeCollection[opt.polygonid] ) {
      console.error(
        'RuntimeError :',
        'An Polygon3D with id ' +
        opt.polygonid +
        ' already exists in this collection.'
      )
      return
    }
    opt = opt || {}
    let maxposition = maxminposition[0].toCartographic().toDegrees()
    let minposition = maxminposition[1].toCartographic().toDegrees()
    let PolygonArray = []
    let oneposition = SSmap.Cartesian3.fromDegrees(
      maxposition.longitude,
      maxposition.latitude,
      this._nowclipdistance + num
    )
    let twoposition = SSmap.Cartesian3.fromDegrees(
      maxposition.longitude,
      minposition.latitude,
      this._nowclipdistance + num
    )
    let threeposition = SSmap.Cartesian3.fromDegrees(
      minposition.longitude,
      minposition.latitude,
      this._nowclipdistance + num
    )
    let fourposition = SSmap.Cartesian3.fromDegrees(
      minposition.longitude,
      maxposition.latitude,
      this._nowclipdistance + num
    )
    PolygonArray.push( oneposition.toVector3() )
    PolygonArray.push( twoposition.toVector3() )
    PolygonArray.push( threeposition.toVector3() )
    PolygonArray.push( fourposition.toVector3() )
    PolygonArray.push( oneposition.toVector3() )
    let optp = {
      color: opt.color || '#FF0000', //边线颜色
      alpha: opt.alpha || 0.2, //边线颜色透明度
      pointArray: PolygonArray, //弧度数组类型
      name: 'Extrude' + opt.polygonid, //实体名称
      show: opt.isshow === undefined ? false : opt.isshow, //显示否
      center: opt.centerpoint,
      hnum: num,
      extrudeHeight: opt.pulygonheight || 0.1
    }
    this._clippolygonCollection[opt.polygonid] = this.ExtrudePolygonGraphics( optp )
  }
  
  //生成裁切面 辅助 东南西北 四个方向
  /**
   *
   * @param {*} recposition 模型四个角坐标
   * @param {*} opt 属性
   * @param {*} num 距离
   * @returns
   */
  addDirPolygon3D ( recposition, opt, num ) {
    var objectnum = Object.getOwnPropertyNames(
      this.ClipCubeCollection
    ).length
    if ( objectnum >= 8 ) {
      console.error(
        'RangeError :',
        'Maximum call Polygon3D value exceeded'
      )
      return
    }
    //相同id 不同重复创建
    if ( this.ClipCubeCollection[opt.polygonid] ) {
      console.error(
        'RuntimeError :',
        'An Polygon3D with id ' +
        opt.polygonid +
        ' already exists in this collection.'
      )
      return
    }
    opt = opt || {}
    //计算向量
    let PolygonObject = this._getVectorByPoint( recposition, opt.type, num )
    
    let optp = {
      color: opt.color || '#FF0000', //边线颜色
      alpha: opt.alpha || 0.2, //边线颜色透明度
      pointArray: PolygonObject.polygonarray, //弧度数组类型
      name: 'Extrude' + opt.polygonid, //实体名称
      show: opt.isshow === undefined ? false : opt.isshow, //显示否
      center: opt.centerpoint,
      extrudeHeight: opt.pulygonheight || 300
    }
    this._clippolygonCollection[opt.polygonid] = this.ExtrudePolygonGraphics( optp )
    return PolygonObject
  }
  
  //计算向量
  _getVectorByPoint ( nowrecposition, type, num ) {
    var returndata = {}
    let PolygonArray = []
    switch ( type ) {
      case 'east':
        var newextendeast = this._extendTodistance(
          nowrecposition.northeast,
          nowrecposition.northwest,
          -num
        )
        var wposition1east = newextendeast.position
        var wposition2east = this._extendTodistance(
          nowrecposition.southeast,
          nowrecposition.southwest,
          -num
        ).position
        PolygonArray.push( nowrecposition.northeast )
        PolygonArray.push( wposition1east.toCartesian3().toVector3() )
        PolygonArray.push( wposition2east.toCartesian3().toVector3() )
        PolygonArray.push( nowrecposition.southeast )
        returndata.pointList = []
        var wposition12east = this._extendTodistance(
          nowrecposition.northeast,
          nowrecposition.northwest,
          num * 2
        ).position
        var wposition22east = this._extendTodistance(
          nowrecposition.southeast,
          nowrecposition.southwest,
          num * 2
        ).position
        returndata.pointList.push(
          wposition12east.toCartesian3().toVector3()
        )
        returndata.pointList.push(
          wposition22east.toCartesian3().toVector3()
        )
        returndata.vector = newextendeast.vector
        returndata.polygonarray = PolygonArray
        break
      case 'west':
        var newextendwest = this._extendTodistance(
          nowrecposition.northwest,
          nowrecposition.northeast,
          num
        )
        var wposition1west = newextendwest.position
        var wposition2west = this._extendTodistance(
          nowrecposition.southwest,
          nowrecposition.southeast,
          num
        ).position
        PolygonArray.push( nowrecposition.northwest )
        PolygonArray.push( wposition1west.toCartesian3().toVector3() )
        PolygonArray.push( wposition2west.toCartesian3().toVector3() )
        PolygonArray.push( nowrecposition.southwest )
        returndata.pointList = []
        var wposition12west = this._extendTodistance(
          nowrecposition.northwest,
          nowrecposition.northeast,
          num * 2
        ).position
        var wposition22west = this._extendTodistance(
          nowrecposition.southwest,
          nowrecposition.southeast,
          num * 2
        ).position
        returndata.pointList.push(
          wposition12west.toCartesian3().toVector3()
        )
        returndata.pointList.push(
          wposition22west.toCartesian3().toVector3()
        )
        returndata.vector = newextendwest.vector
        returndata.polygonarray = PolygonArray
        break
      case 'south':
        var newextendsouth = this._extendTodistance(
          nowrecposition.southeast,
          nowrecposition.northeast,
          num
        )
        var wposition1south = newextendsouth.position
        var wposition2south = this._extendTodistance(
          nowrecposition.southwest,
          nowrecposition.northwest,
          num
        ).position
        PolygonArray.push( nowrecposition.southeast )
        PolygonArray.push( wposition1south.toCartesian3().toVector3() )
        PolygonArray.push( wposition2south.toCartesian3().toVector3() )
        PolygonArray.push( nowrecposition.southwest )
        
        returndata.pointList = []
        var wposition12south = this._extendTodistance(
          nowrecposition.southeast,
          nowrecposition.northeast,
          num * 2
        ).position
        var wposition22south = this._extendTodistance(
          nowrecposition.southwest,
          nowrecposition.northwest,
          num * 2
        ).position
        returndata.pointList.push(
          wposition12south.toCartesian3().toVector3()
        )
        returndata.pointList.push(
          wposition22south.toCartesian3().toVector3()
        )
        returndata.vector = newextendsouth.vector
        returndata.polygonarray = PolygonArray
        break
      case 'north':
        var newextendnorth = this._extendTodistance(
          nowrecposition.northeast,
          nowrecposition.southeast,
          -num
        )
        var wposition1north = newextendnorth.position
        var wposition2north = this._extendTodistance(
          nowrecposition.northwest,
          nowrecposition.southwest,
          -num
        ).position
        PolygonArray.push( nowrecposition.northeast )
        PolygonArray.push( wposition1north.toCartesian3().toVector3() )
        PolygonArray.push( wposition2north.toCartesian3().toVector3() )
        PolygonArray.push( nowrecposition.northwest )
        
        returndata.pointList = []
        var wposition12north = this._extendTodistance(
          nowrecposition.northeast,
          nowrecposition.southeast,
          num * 2
        ).position
        var wposition22north = this._extendTodistance(
          nowrecposition.northwest,
          nowrecposition.southwest,
          num * 2
        ).position
        returndata.pointList.push(
          wposition12north.toCartesian3().toVector3()
        )
        returndata.pointList.push(
          wposition22north.toCartesian3().toVector3()
        )
        returndata.vector = newextendnorth.vector
        returndata.polygonarray = PolygonArray
        break
      default:
        //默认 东边
        var newextend = this._extendTodistance(
          nowrecposition.northeast,
          nowrecposition.northwest,
          -0.1
        )
        var wposition1 = newextend.position
        var wposition2 = this._extendTodistance(
          nowrecposition.southeast,
          nowrecposition.southwest,
          -0.1
        ).position
        PolygonArray.push( nowrecposition.northeast )
        PolygonArray.push( wposition1.toCartesian3().toVector3() )
        PolygonArray.push( wposition2.toCartesian3().toVector3() )
        PolygonArray.push( nowrecposition.southeast )
        
        returndata.pointList = []
        var wposition12 = this._extendTodistance(
          nowrecposition.northeast,
          nowrecposition.northwest,
          -0.1 * 2
        ).position
        var wposition22 = this._extendTodistance(
          nowrecposition.southeast,
          nowrecposition.southwest,
          -0.1 * 2
        ).position
        returndata.pointList.push(
          wposition12.toCartesian3().toVector3()
        )
        returndata.pointList.push(
          wposition22.toCartesian3().toVector3()
        )
        returndata.vector = newextend.vector
        returndata.polygonarray = PolygonArray
        break
    }
    return returndata
  }
  
  /**
   *
   * @param { TilesetLayer } T 裁剪对象 模型之类
   * @returns 裁剪范围
   */
  getTilesrectangle ( T ) {
    if ( T ) {
      
      //if ( Object.getPrototypeOf( T ).constructor === SSmap.Tileset ) {
      let positionrectangle = T.rectangle //矩阵
      let nowsouthwest = positionrectangle
        .southwest()
        .toCartesian3()
        .toVector3()
      let nownorthwest = positionrectangle
        .northwest()
        .toCartesian3()
        .toVector3()
      
      let nownortheast = positionrectangle
        .northeast()
        .toCartesian3()
        .toVector3()
      let nowsoutheast = positionrectangle
        .southeast()
        .toCartesian3()
        .toVector3()
      
      let maxposition = this._extendTodistance(
        nownortheast,
        nowsoutheast,
        this._cumdistance
      ).position
      let minposition = this._extendTodistance(
        nowsouthwest,
        nownorthwest,
        this._cumdistance
      ).position
      
      return {
        maxmin: [
          maxposition.toCartesian3(),
          minposition.toCartesian3()
        ],
        recposition: {
          southwest: nowsouthwest,
          northwest: nownorthwest,
          northeast: nownortheast,
          southeast: nowsoutheast
        }
        //}
      }
    }
  }
  
  //随机id ~ 工具
  _getentityid () {
    let d = new Date()
    let n = d.getTime() + Math.random()
    return n.toString( 32 )
  }
  
  /**
   * @description 计算中心点
   * @param { list } points 笛卡尔坐标数组 Cartesian3
   * @param { Number } h 中心点初始高度
   * @return point
   */
  _gettpointCenter ( points, h ) {
    //if ( !( Object.getPrototypeOf( points ).constructor === Array ) ) return
    //if ( !( Object.getPrototypeOf( points[0] ).constructor === SSmap.Cartesian3 ) ) return
    let PVX = Number.MAX_VALUE //x的最大值
    let PVY = Number.MAX_VALUE //y的最大值
    let PVZ = Number.MAX_VALUE //z的最大值
    let NVX = -Number.MAX_VALUE //-x的最大值
    let NVY = -Number.MAX_VALUE //-y的最大值
    let NVZ = -Number.MAX_VALUE //-z的最大值
    if ( points.length === 0 ) {
      console.error( '只有一个点，无法计算' )
    } else if ( points.length === 1 ) {
      console.error( '有两个点，无法计算' )
    } else {
      for ( let i = 0; i < points.length; i++ ) {
        if ( points[i].x < PVX ) {
          PVX = points[i].x
        }
        if ( points[i].y < PVY ) {
          PVY = points[i].y
        }
        if ( points[i].z < PVZ ) {
          PVZ = points[i].z
        }
        if ( points[i].x > NVX ) {
          NVX = points[i].x
        }
        if ( points[i].y > NVY ) {
          NVY = points[i].y
        }
        if ( points[i].z > NVZ ) {
          NVZ = points[i].z
        }
      }
      let l = SSmap.Vector3.create(
        ( NVX + PVX ) / 2,
        ( NVY + PVY ) / 2,
        ( NVZ + PVZ ) / 2
      )
      if ( this._viewer.scene.globe ) {
        var position = l.toCartesian3().toCartographic().toDegrees()
        var nowh = position.height > 0 ? position.height : 0
        var newL = SSmap.Cartesian3.fromDegrees(
          position.longitude,
          position.latitude,
          h || nowh
        )
        return newL.toVector3()
      } else {
        return {
          lon: l.x,
          lat: l.y,
          height: l.z
        }
      }
    }
  }
  
  _getnewvectorposition ( startpoint, normal, num ) {
    if ( Object.getPrototypeOf( startpoint ).constructor === SSmap.Cartographic ) {
      startpoint = startpoint.toCartesian3()
    }
    if ( normal ) {
      let nownormal = SSmap.Vector3.create(
        normal.x * num,
        normal.y * num,
        normal.z * num
      )
      let nowposition = SSmap.Vector3.create(
        startpoint.x + nownormal.x,
        startpoint.y + nownormal.y,
        startpoint.z + nownormal.z
      )
      return nowposition.toCartographic()
    }
  }
  
  /**
   * 延伸几米
   * @return newpoint 返回新的延伸坐标
   * @param {Vector3} startpoint  需要延伸的坐标
   * @param {Vector3} endpoint  作为方向的延伸坐标辅助
   * @param {Number} num  几米
   * @returns
   */
  _extendTodistance ( startpoint, endpoint, num ) {
    num = num || 1
    //if ( !( Object.getPrototypeOf( startpoint ).constructor === SSmap.Vector3 ) ) return
    //if ( !( Object.getPrototypeOf( endpoint ).constructor === SSmap.Vector3 ) ) return
    let normal = SSmap.Vector3.subtract( startpoint, endpoint ).normalize()
    if ( normal ) {
      let nownormal = SSmap.Vector3.create(
        normal.x * num,
        normal.y * num,
        normal.z * num
      )
      let nowposition = SSmap.Vector3.create(
        startpoint.x + nownormal.x,
        startpoint.y + nownormal.y,
        startpoint.z + nownormal.z
      )
      return {
        vector: normal, //向量
        position: nowposition.toCartographic()
      }
    } else {
      return null
    }
  }
  
  /**
   *
   * @param {Object} maxminposition
   * @param {Vector3} center
   * @returns
   */
  _getwidthheightangle ( maxminposition, center ) {
    //if (
    //  !( Object.getPrototypeOf( maxminposition.southwest ).constructor === SSmap.Vector3 ) &&
    //  !( Object.getPrototypeOf( maxminposition.northwest ).constructor === SSmap.Vector3 ) &&
    //  !( Object.getPrototypeOf( maxminposition.northeast ).constructor === SSmap.Vector3 ) &&
    //  !( Object.getPrototypeOf( maxminposition.southeast ).constructor === SSmap.Vector3 )
    //)
    //  return
    let nowheight =
      maxminposition.southeast.distance( maxminposition.northeast ) +
      this._cumdistance
    let nowwidth =
      maxminposition.southeast.distance( maxminposition.southwest ) +
      this._cumdistance
    //中心点 最大坐标 的方位角度
    //var one = center.toCartographic().toDegrees()
    //var two = maxminposition.northeast.toCartographic().toDegrees()
    //var pt1 = {
    //  type: 'Feature',
    //  geometry: {
    //    type: 'Point',
    //    coordinates: [ one.longitude, one.latitude, 0 ]
    //  }
    //}
    //var pt2 = {
    //  type: 'Feature',
    //  geometry: {
    //    type: 'Point',
    //    coordinates: [ two.longitude, two.latitude, 0 ]
    //  }
    //}
    //var nowbearing = this._callBack( pt1, pt2 )
    //turf.rhumbBearing( pt1, pt2 ) //角度
    return {
      width: nowwidth,
      height: nowheight
      //bearing: nowbearing
    }
  }
  
  setBear ( callback ) {
    callback( this.pt1, this.pt2 )
  }
  
  _Vector3toCartesian3 ( points ) {
    var newpoints = []
    for ( var i = 0; i < points.length; i++ ) {
      var point = points[i]
      if ( Object.getPrototypeOf( point ).constructor === SSmap.Vector3 ) {
        newpoints.push( point.toCartesian3() )
      } else {
        newpoints.push( point )
      }
    }
    return newpoints
  }
  
  //经纬度坐标数组转 弧度Cartographic坐标数组
  _lonlatsToCartographics ( lonLats ) {
    var newCartographic = []
    if ( Object.getPrototypeOf( lonLats ).constructor === Array ) {
      for ( var i = 0; i < lonLats.length; i++ ) {
        var lonlat = lonLats[i]
        if ( Object.getPrototypeOf( lonlat ).constructor === SSmap.Degrees ) {
          var cartographic = lonlat.toCartographic()
          newCartographic.push( cartographic )
        }
      }
      return newCartographic
    }
  }
  
  //四方向 的中心点
  _getcentersquare ( nowpoobject, nowheight ) {
    var squareobj = {}
    if ( nowpoobject.pointList.length === 2 ) {
      var points = nowpoobject.pointList
      squareobj.distance = points[0].distance( points[1] )
      squareobj.squareposition = []
      for ( var i = 0; i < points.length; i++ ) {
        var point = points[i]
        var degress = point.toCartesian3().toCartographic().toDegrees()
        squareobj.squareposition.push( point.toCartesian3() )
        var newpoint = SSmap.Cartesian3.fromDegrees(
          degress.longitude,
          degress.latitude,
          nowheight
        )
        squareobj.squareposition.push( newpoint )
      }
    }
    return squareobj
  }
  
  /**
   * 拉伸多边形 立体
   * @param {*} opt
   */
  ExtrudePolygonGraphics ( opt ) {
    opt = opt || {}
    //创建点
    var outer = new SSmap.Cartesian3Vector()
    opt.pointArray.forEach( ( item, index, array ) => {
      //笛卡尔坐标添加
      //if ( Object.getPrototypeOf( item ).constructor === SSmap.Vector3 ) {
      //  var ddd = item.toCartesian3()
      outer.push_back( item.toCartesian3() )
      //} else if ( Object.getPrototypeOf( item ).constructor === SSmap.Cartesian3 ) {
      //  outer.push_back( item )
      //}
    } )
    
    var extrudeEntity = new SSmap.ExtrudeEntity()
    extrudeEntity.setOuter( outer )
    extrudeEntity.extrudeHeight = opt.extrudeHeight || 0.1
    extrudeEntity.roofColor = this.colorToRGB(
      opt.color || '#FF0000',
      opt.alpha || 1.0
    ) //顶部填充颜色
    extrudeEntity.color = this.colorToRGB(
      opt.color || '#FF0000',
      opt.alpha || 1.0
    ) //颜色
    extrudeEntity.alpha = opt.alpha || 0.2 //透明度
    extrudeEntity.roofAlpha = opt.alpha || 0.2 //透明度
    extrudeEntity.create()
    var ent = extrudeEntity.createEntity()
    ent.enabled = opt.show
    this._viewer.scene.addEntity( ent )
    ent.objectName = opt.name || ''
    ent.attribute = opt || ''
    extrudeEntity.delete()
    outer.delete()
    return ent
  }
  
  //颜色16进制转rgb ~ 工具
  colorToRGB ( color, a ) {
    let color1, color2, color3
    color = '' + color
    if ( typeof color !== 'string' ) return
    if ( color.charAt( 0 ) === '#' ) {
      color = color.substring( 1 )
    }
    if ( color.length === 3 ) {
      color =
        color[0] + color[0] + color[1] + color[1] + color[2] + color[2]
    }
    if ( /^[0-9a-fA-F]{6}$/.test( color ) ) {
      color1 = parseInt( color.substr( 0, 2 ), 16 )
      color2 = parseInt( color.substr( 2, 2 ), 16 )
      color3 = parseInt( color.substr( 4, 2 ), 16 )
      //return "rgb(" + color1 + "," + color2 + "," + color3 + ")";
      //return [color1, color2, color3, Math.round(Number(a) * 255)];
      return SSmap.Color.fromRgb(
        color1,
        color2,
        color3,
        Math.round( Number( a ) * 255 )
      )
    }
  }
}

export default DClipVolume
